/**
 * 通用js方法封装处理
 * Copyright (c) 2024 Youcan
 */

/** 表格类型 */
const TABLE_TYPE = {
    GRID: 0,
    TREE: 1
};

/** 消息状态码 */
const WEB_STATUS = {
    SUCCESS: 0,
    FAIL: 500,
    NO_AUTH: 403,
    WARNING: 301
};

/** 弹窗状态码 */
const MODAL_STATUS = {
    SUCCESS: "success",
    FAIL: "error",
    WARNING: "warning"
};

const DEFAULTS = {
    mainTable: 'data-table',
    mainQueryPanel: 'query-panel',
    mainQueryFormFilter: 'query-form',

    GRID_TABLE_OPTIONS: {},
};

const INSTANCES = {
    // 所有实例对象
    instances: new Map(),
    // 设置实例配置
    set: (id, obj) => {
        INSTANCES.instances.set(id, obj);
    },
    // 获取实例配置
    get: (id) => {
        return INSTANCES.instances.get(id);
    },
};

/*
 * 当前table相关信息
 */
var table = {
    id: DEFAULTS.mainTable, // 数据表格的ID
    tableType: TABLE_TYPE.GRID, // 数据表格的类型：GRID 网格表格，TREE 树型表格
    layTable: layui.table, // 与表格相关的layui插件实例
    configs: {
        module: { // 业务模块信息
            name: 'Youcan',
            path: '',
            addUrl: this.path + 'add',
            addChildUrl: this.path + 'addChild',
            removeUrl: this.path + 'remove',
            batchRemoveUrl: this.path + 'batchRemove',
            clearUrl: this.path + 'clear',
            editUrl: this.path + 'edit',
            expandAllUrl: this.path + 'expandAll',
            importAllUrl: this.path + 'importAll',
        },
        right: {
            add: false,
            batchRemove: false,
            clear: false,
            expandAll: false,
            foldAll: false,
            addChild: false,
            edit: false,
            remove: false,
            importAll: false,
        },
        queryPanel: {
            id: DEFAULTS.mainQueryPanel,
            formFilter: DEFAULTS.mainQueryFormFilter,
        },
        modal: {
            area: ['720px', '95%'] // 模态窗口的默认大小
        },
    },
    options: {
        elem: '#' + DEFAULTS.mainTable, // 数据表格的默认ID
        method: 'post', // 请求的方式
        cellExpandedMode: 'tips', // 单元格默认展开方式
        request: {pageName: 'pageNumber', limitName: 'pageSize'}, // 定义分页请示参数名
        defaultToolbar: [{title: '查询', layEvent: 'toggle', icon: 'layui-icon-search'}, 'filter'], // 头部工具栏右侧图标
        height: 'full-100', // 表格容器高度
        page: true, // 默认开启分页
        limits: [10, 25, 50, 75, 100],
        title: 'Youcan',
        autoSort: false,
        tree: { // treeTable 组件的特定属性集
            customName: { // 定义属性名的集合
                icon: "customIcon" // 定义图标的属性名称
            },
            view: { // 视图相关的属性集合
                dblClickExpand: false, // 双击节点时，不展开节点
                expandAllDefault: true, // 默认展开全部节点
                showIcon: true, // 显示节点图标
            },
            data: { // 数据相关的属性集合
                rootPid: '0', // 设置根节点的 pid 属性值
                cascade: 'none', // 设置复选的级联方式
            },
        }
    },
    // 记住选择实例组
    rememberSelecteds: {},
    // 记住选择ID组
    rememberSelectedIds: {}
};

layui.use(['table', 'treeTable', 'form', 'jquery', 'common'], () => {
});

(function ($ = layui.jquery) {
    $.extend({
        common: {
            // 判断对象是否为空
            isNull: function (value) {
                if (value == null || value == undefined || value == "undefined") {
                    return true;
                }
                return false;
            },
            // 判断对象是否为空
            isNotNull: function (value) {
                if (value == null || value == undefined || value == "undefined") {
                    return true;
                }
                return false;
            },
            // 判断字符串是否为空
            isEmpty: function (value) {
                if (value == null || this.trim(value) == "" || value == undefined || value == "undefined") {
                    return true;
                }
                return false;
            },
            // 判断一个字符串是否为非空串
            isNotEmpty: function (value) {
                return !$.common.isEmpty(value);
            },
            // 如果值是空，则返回指定默认字符串，否则返回字符串本身
            nullToDefault: function (value, defaultValue) {
                return $.common.isEmpty(value) ? defaultValue : value;
            },
            // 空对象转字符串
            nullToStr: function (value) {
                if ($.common.isEmpty(value)) {
                    return "-";
                }
                return value;
            },
            // 空格截取
            trim: function (value) {
                if (value == null) {
                    return "";
                }
                return value.toString().replace(/(^\s*)|(\s*$)|\r|\n/g, "");
            },
            // 比较两个字符串（大小写敏感）
            equals: function (str, that) {
                return str == that;
            },
            // 比较两个字符串（大小写不敏感）
            equalsIgnoreCase: function (str, that) {
                return String(str).toUpperCase() === String(that).toUpperCase();
            },
            // 将字符串按指定字符分割
            split: function (str, sep, maxLen) {
                if ($.common.isEmpty(str)) {
                    return null;
                }
                var value = String(str).split(sep);
                return maxLen ? value.slice(0, maxLen - 1) : value;
            },
            // 日期格式化 时间戳  -> yyyy-MM-dd HH:mm:ss
            dateFormat: function (date, format = 'yyyy-MM-dd HH:mm:ss') {
                if ($.common.isEmpty(date)) return '';
                return layui.util.toDateString(date, format);
            },
            // 判断是否移动端
            isModile: () => {
                return navigator.userAgent.match(/(Android|iPhone|SymbianOS|Windows Phone|iPad|iPod)/i);
            },
            // 判断是否函数
            isFunction: (obj) => {
                return typeof obj == "function"
            },
        },
        /*
         * 数据表格封装处理
         */
        table: {
            init: (configs, options) => {
                // 创建表格对象theTable
                var theTable = Object.assign({}, table);
                var configs = $.extend(theTable.configs, configs); // 覆盖默认参数
                var options = $.extend(table.options, options);

                // 处理id，id以Layui表格参数options中的elem为准，如果以#开头，则去掉#号
                theTable.id = options.elem.replaceAll('#', '');
                options.elem = '#' + theTable.id;

                // 通过configs.tableType区分是layui.table和layui.treeTable实例
                theTable.layTable = $.table.layTable(configs);

                // 将theTable保存到INSTANCES
                INSTANCES.set(theTable.id, theTable);

                // 初始化表格事件监听
                $.table.initEvent(theTable.id);

                // 按queryForm中的内容查询表格
                $.table.search(theTable.id, configs.queryPanel.formFilter);

                // 初始化查询面板
                $.form.init(configs, theTable.id);
            },
            search: (tableId = DEFAULTS.mainTable, queryFormFilter = DEFAULTS.mainQueryFormFilter) => {
                var theTable = INSTANCES.get(tableId);
                if ($.common.isNull(theTable)) return;
                var options = theTable.options;

                // 从查询表单中获取参数
                options.where = layui.form.val(queryFormFilter);

                // options中的默认排序参数带入到where参数中
                if (options.initSort) {
                    options.where.sortField = options.initSort.field;
                    options.where.sortType = options.initSort.type;
                }

                // 渲染表格
                return theTable.layTable.render(options);
            },
            refresh: (tableId = DEFAULTS.mainTable) => {
                var theTable = INSTANCES.get(tableId);
                if ($.common.isNull(theTable)) return;
                theTable.layTable.reload(tableId, theTable.options, false);
            },
            initTableToolbar: (configs, buttons = '') => {
                var right = $.extend(table.configs.right, configs.right);
                var str = '<div className="layui-btn-group">';
                if (right.add) str += '<a class="layui-btn layui-btn-sm" round lay-event="add"><i class="layui-icon layui-icon-add-1"></i>&nbsp;新增</a>';
                if (right.batchRemove) str += '<a class="layui-btn layui-btn-sm layui-bg-red" round lay-event="batchRemove"><i class="layui-icon layui-icon-delete"></i>&nbsp;批量删除</a>';
                if (right.clear) str += '<a class="layui-btn layui-btn-sm layui-bg-red" round lay-event="clearAll"><i class="layui-icon layui-icon-close"></i>&nbsp;清空</a>';
                if (right.expandAll) str += '<a class="layui-btn layui-btn-sm layui-btn-primary" round lay-event="expandAll"><i class="layui-icon layui-icon-spread-left"></i>&nbsp;展开</a>';
                if (right.foldAll) str += '<a class="layui-btn layui-btn-sm layui-btn-primary" round lay-event="foldAll"><i class="layui-icon layui-icon-shrink-right"></i>&nbsp;折叠</a>';
                str += buttons + '</dev>'
                return str;
            },
            initRowToolbar: (configs, buttons = '') => {
                var right = $.extend(table.configs.right, configs.right);
                var str = '<div className="layui-btn-group">';
                if (right.addChild) str += '<a class="layui-btn layui-btn-xs" plain lay-event="addChild"><i class="layui-icon layui-icon-add-1"></i>&nbsp;新增</a>';
                if (right.edit) str += '<a class="layui-btn layui-btn-xs layui-bg-orange" plain lay-event="edit"><i class="layui-icon layui-icon-edit"></i>&nbsp;编辑</a>';
                if (right.remove) str += '<a class="layui-btn layui-btn-xs layui-bg-red" plain lay-event="remove"><i class="layui-icon layui-icon-delete"></i>&nbsp;删除</a>';
                str += buttons + '</dev>'
                return str;
            },
            initEvent: (tableId) => {
                var theTable = INSTANCES.get(tableId);
                if ($.common.isNull(theTable)) return;
                /*
                 * 监听表格上方的工具条按钮事件
                 */
                theTable.layTable.on('toolbar(' + theTable.id + ')', (obj) => {
                    if (obj.event == 'add') {
                        console.log('add');
                    }
                    if (obj.event == 'batchRemove') {
                        console.log('batchRemove');
                    }
                    if (obj.event == 'clearAll') {
                        console.log('clearAll');
                    }
                    if (obj.event == 'expandAll') {
                        console.log('expandAll');
                    }
                    if (obj.event == 'foldAll') {
                        console.log('foldAll');
                    }
                    if (obj.event == 'toggle') {
                        console.log('toggle');
                    }
                });

                /*
                 * 监听表格的行双击事件
                 */
                theTable.layTable.on('rowDouble(' + theTable.id + ')', (obj) => {
                    console.log('doubleClick');
                });

                /*
                 * 监听表格中每条记录后方的操作
                 */
                theTable.layTable.on('tool(' + theTable.id + ')', (obj) => {
                    if (obj.event === 'addChild') {
                        console.log('addChild');
                    }
                    if (obj.event === 'edit') {
                        console.log('edit');
                        $.table.edit(theTable.id, obj);
                    }
                    if (obj.event === 'remove') { //
                        console.log('remove');
                    }
                });

                /*
                 * 监听表格标题头部排序切换小箭头
                 */
                theTable.layTable.on('sort(' + theTable.id + ')', (obj) => {
                    // 查询数据表格
                    console.log('sort');
                });
            },
            layTable(configs) {
                return configs.tableType == TABLE_TYPE.TREE ? layui.treeTable : layui.table;
            },
            /*
             * 新建记录
             */
            add: (tableId = DEFAULTS.mainTable, obj) => {
                var url = MODULE_PATH + "add";
                window.dataTable.addOrEdit("<i class='layui-icon layui-icon-add-1'></i>&nbsp;&nbsp;新增", url, "post", "add");
            },
            /*
             * 新建子项记录
             */
            addChild: (tableId = DEFAULTS.mainTable, obj) => {
                var url = MODULE_PATH + "add?parentId=" + obj.data['id'];
                window.dataTable.addOrEdit("<i class='layui-icon layui-icon-add-1'></i>&nbsp;&nbsp;新增", url, "post", "add");
            },
            /*
             * 编辑记录
             */
            edit: (tableId = DEFAULTS.mainTable, obj) => {
                var theTable = INSTANCES.get(tableId);
                var url = theTable.configs.module.path + "edit?id=" + obj.data['id'];
                //$.table.addOrEdit("<i class='layui-icon layui-icon-edit'></i>&nbsp;&nbsp;编辑", url, "put", "edit", theTable.configs.modal.area);
                $.modal.open("<i class='layui-icon layui-icon-edit'></i>&nbsp;&nbsp;编辑", url, theTable.configs.modal.area, "put")
            },
            /*
             * 新增或编辑记录总方法
             */
            addOrEdit: (title, url, method, action, area) => {
                layer.open({
                    type: 2,
                    title: title,
                    content: url,
                    area: area,
                    anim: 6,
                    moveOut: false,
                    resize: false,
                    skin: 'layui-layer-molv',
                    shadeClose: true,
                    btn: ['保存', '取消'],
                    yes: (index, layero) => {
                        var iframeWindow = window['layui-layer-iframe' + index],
                            submitID = 'data-save', // 此ID必须和弹出iframe窗口中提交按钮的ID和Filter值一致
                            submit = layero.find('iframe').contents().find("#" + submitID);

                        // 监听提交
                        iframeWindow.layui.form.on('submit(' + submitID + ')', function (data) {
                            $.ajax({ // 用Ajax替换弹窗中的提交
                                url: MODULE_PATH + action,
                                type: method,
                                data: data.field, // 获取提交的数据
                                beforeSend: () => {
                                    layer.load();
                                }, // 防止重复操作
                                complete: () => {
                                    layer.closeAll('loading');
                                }, //解除防重复操作
                                success: (result) => {
                                    if (result.code == 200) {
                                        // 提交 Ajax 成功后，静态更新表格中的数据
                                        window.dataTable.refresh(); // 数据表格刷新
                                        layer.close(index); //关闭弹层
                                    } else {
                                        if (result.description) {
                                            // Ajax调用成功，但后台返回失败信息
                                            layer.alert(result.description, {icon: 5});
                                        } else {
                                            layer.alert("操作失败！", {icon: 2});
                                        }
                                    }
                                },
                                error: function (e) { // Ajax调用失败
                                    layer.alert("操作失败：" + e.responseText, {icon: 2});
                                }
                            });
                            return false; // 一定要返回False来阻止弹出窗口中提交按钮的再次提交
                        });

                        submit.trigger('click'); // 这里触发弹出窗口的提交按钮
                    }
                });
            },
            /*
             * 多记录移除
             */
            batchRemove: (tableId = DEFAULTS.mainTable, obj) => {
                var checkedIds = common.checkField(obj, 'id');

                if (checkedIds === "") {
                    layer.msg("未选中任何记录", {
                        icon: 3,
                        time: 1000
                    });
                    return false;
                }
                window.dataTable.removeByIds(checkedIds);
            },
            /*
             * 单记录移除
             */
            remove: (tableId = DEFAULTS.mainTable, obj) => {
                window.dataTable.removeByIds(obj.data['id']);
            },
            /*
             * 通过ID表移除记录
             */
            removeByIds: (ids = []) => {
                layer.confirm('确定要删除选择的记录？', {
                    icon: 3,
                    title: '提示'
                }, (index) => {
                    layer.close(index);
                    $.ajax({
                        url: MODULE_PATH + "delete",
                        dataType: 'json',
                        type: 'delete',
                        data: {"ids": ids},
                        beforeSend: () => {
                            layer.load();
                        }, // 防止重复操作
                        complete: () => {
                            layer.closeAll('loading');
                        }, //解除防重复操作
                        success: (result) => {
                            if (result.code == 200) {
                                // 提交 Ajax 成功后，静态更新表格中的数据
                                window.dataTable.refresh(); // 数据表格刷新
                            } else {
                                if (result.description) {
                                    // Ajax调用成功，但后台返回失败信息
                                    layer.alert(result.description, {icon: 5});
                                } else {
                                    layer.alert("操作失败！", {icon: 2});
                                }
                            }
                        }
                    })
                });
            },
            /*
             * 查看记录详情
             */
            detail: (tableId = DEFAULTS.mainTable, obj) => {
                layer.open({
                    type: 2,
                    title: "<i class='layui-icon layui-icon-survey'></i>&nbsp;&nbsp;查看",
                    content: MODULE_PATH + "detail?id=" + obj.data['id'],
                    maxmin: false,
                    area: POPUP_AREA,
                    closeBtn: 1,
                    shadeClose: false,
                    anim: 1,
                    moveOut: false,
                    resize: false,
                    btn: ['关闭'],
                    yes: (index, layero) => {
                        layer.close(index); // 关闭弹层
                    }
                });
            },
            /*
             * 导入Excel数据
             */
            importExcel: (tableId = DEFAULTS.mainTable) => {

            },
            /*
             * 导出成Excel
             */
            exportExcel: (tableId = DEFAULTS.mainTable) => {

            },
            /*
             * 清空所有记录
             */
            clearAll: (tableId = DEFAULTS.mainTable) => {
                layer.confirm("确认清空所有记录吗？", {
                    icon: 3,
                    title: '确认'
                }, (index) => {
                    layer.close(index);
                    $.ajax({
                        url: MODULE_PATH + "clear",
                        method: "post",
                        data: form.val("query-form"),
                        beforeSend: () => {
                            layer.load();
                        }, // 防止重复操作
                        complete: () => {
                            layer.closeAll('loading');
                        }, //解除防重复操作
                        success: (result) => {
                            if (result.code == 200) {
                                layer.alert("操作成功！", {icon: 1});
                                window.dataTable.search();
                            } else {
                                if (result.description) {
                                    // Ajax调用成功，但后台返回失败信息
                                    layer.alert(result.description, {icon: 5});
                                } else {
                                    layer.alert("操作失败！", {icon: 2});
                                }
                            }
                        }
                    });
                });
            },
        },

        /*
         * 表单封装处理
         */
        form: {
            init: (configs, tableId = DEFAULTS.mainTable) => {
                if ($.common.isModile()) $('#' + configs.queryPanelId).hide();

            },
            toggle: (id = DEFAULTS.mainQueryPanel) => {
                if ($("#" + id).css("display") == "none") {
                    $("#" + id).show("fast");
                } else {
                    $("#" + id).hide("fast");
                }
            },
            getData: (filter = DEFAULTS.mainQueryFormFilter) => {
                layui.form.val(filter);
            },
            search: (filter = DEFAULTS.mainQueryFormFilter, tableId = DEFAULTS.mainTable) => {
                $.table.search(tableId, filter);
            },
            reset: (filter = DEFAULTS.mainQueryFormFilter, tableId = DEFAULTS.mainTable) => {
                $('[lay-filter="' + filter + '"]')[0].reset();
                $.form.search(filter, tableId);
            },
        },
        /*
         * 弹出层封装处理
         */
        modal: {
            // 弹出层指定宽度
            open: function (title, url, area, method, callback) {
                if ($.common.isEmpty(title)) {
                    title = false;
                }
                if ($.common.isEmpty(url)) {
                    url = "/404.html";
                }
                if ($.common.isEmpty(callback)) {
                    callback = function(index, layero) {
                        var iframeWin = layero.find('iframe')[0];
                        iframeWin.contentWindow.submitHandler(index, layero);
                    }
                }
                top.layer.open({
                    type: 2,
                    area: area,
                    fix: false,
                    //不固定
                    maxmin: true,
                    shade: 0.3,
                    title: title,
                    content: url,
                    btn: ['确定', '关闭'],
                    // 弹层外区域关闭
                    shadeClose: true,
                    yes: callback,
                    cancel: function(index) {
                        return true;
                    },
                    success: function () {
                        $(':focus').blur();
                    }
                });
            },
            // 弹出层指定参数选项
            openOptions: function (options) {
                var _url = $.common.isEmpty(options.url) ? "/404.html" : options.url;
                var _title = $.common.isEmpty(options.title) ? "系统窗口" : options.title;
                var _width = $.common.isEmpty(options.width) ? "800" : options.width;
                var _height = $.common.isEmpty(options.height) ? ($(window).height() - 50) : options.height;
                var _btn = ['<i class="fa fa-check"></i> 确认', '<i class="fa fa-close"></i> 关闭'];
                // 如果是移动端，就使用自适应大小弹窗
                if ($.common.isMobile()) {
                    _width = 'auto';
                    _height = 'auto';
                }
                if ($.common.isEmpty(options.yes)) {
                    options.yes = function(index, layero) {
                        options.callBack(index, layero);
                    }
                }
                var btnCallback = {};
                if (options.btn instanceof Array){
                    for (var i = 1, len = options.btn.length; i < len; i++) {
                        var btn = options["btn" + (i + 1)];
                        if (btn) {
                            btnCallback["btn" + (i + 1)] = btn;
                        }
                    }
                }
                var index = top.layer.open($.extend({
                    id: options.id,       // 唯一id
                    anim: options.anim,   // 弹出动画 0-6
                    type: 2,
                    maxmin: $.common.isEmpty(options.maxmin) ? true : options.maxmin,
                    shade: 0.3,
                    title: _title,
                    fix: false,
                    area: [_width + 'px', _height + 'px'],
                    content: _url,
                    shadeClose: $.common.isEmpty(options.shadeClose) ? true : options.shadeClose,
                    skin: options.skin,
                    // options.btn设置为0表示不显示按钮
                    btn: $.common.isEmpty(options.btn) ? _btn : options.btn,
                    yes: options.yes,
                    cancel: function () {
                        return true;
                    },
                    success: function () {
                        $(':focus').blur();
                    }
                }, btnCallback));
                if ($.common.isNotEmpty(options.full) && options.full === true) {
                    top.layer.full(index);
                }
            },

        },

        tree: {},

        // 校验封装处理
        validate: {
            // 表单验证
            form: function (formId) {
                var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId;
                return $("#" + currentId).validate().form();
            },
            // 重置表单验证（清除提示信息）
            reset: function (formId) {
                var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId;
                return $("#" + currentId).validate().resetForm();
            }
        },
    });
})();

